import zutil from '../utils/zip';

var promise_retry = function (actual_promise_func, retries, condi) {
  /**
   * 发生错误 & 满足条件时, 自动重试.
   */
  return function () {
    var aarguments = Array.prototype.slice.call(arguments, 0); // convert to a javascript array.
    var d = new Promise(function (resolve, reject) {
      var re_call = function (re_args, call_times) {
        actual_promise_func.apply(null, re_args).then(function () {
          var aarguments = Array.prototype.slice.call(arguments, 0); // convert to a javascript array.
          resolve.apply(d, aarguments);
        }).catch(function (err) {
          if (!condi || (typeof condi === 'function' && condi(err))) {  // 只有在已知的错误时,才自动重试
            if (call_times < retries) {   // 重试次数
              setTimeout(function () {    // 延迟重试
                re_call(re_args, call_times + 1);
              }, 100);
              return;
            }
          }
          reject.apply(d, [err]);
        });
      };
      re_call(aarguments, 1);
    });
    return d;
  };
}, unzip = function (zippedBlob) {
  return new Promise(function (resolve, reject) {
    var jsonfn = 'tables.json';
    zutil.unzipBlob(jsonfn, zippedBlob, function (unzippedBlob) {
      if (unzippedBlob !== undefined) {
        var reader = new FileReader();
        reader.onload = function (e) {
          try {
            var dataObj = JSON.parse(e.target.result);
            resolve(dataObj);
          } catch (err) {
            reject(err);
          }
        };
        reader.readAsText(unzippedBlob);
      }
    }, function (err) { // on error handler
      reject(err);
    });
  });
}, _load_inner = function () {
  return fetch('tables.map.zip').then(function (e) {
    return e.blob().then(function (b) {
      return unzip(b);
    });
  })
}, load_remote = promise_retry(_load_inner, 3, function (err) {
  return true // 发生错误时, 无条件重试
}), _stroe = undefined, load = function () {
  if (_stroe === undefined) {
    return load_remote().then(function (e) {
      _stroe = e;
    });
  } else {
    return Promise.resolve(_stroe);
  }
}, get = function () {
  return _stroe;
}, set = function (tables) {
  _stroe = tables;
}, save = function () {
  // zutil
};



export default {
  loadData: load,
  getData: get,
  setData: set,
  saveToFile: save
}